import {defineStore} from "pinia";
import {dictApi} from "@/api/dict";
import {booleanToNumber, isNotEmpty} from "@/utils";
import {SysDict} from "@/api/dict/types.ts";
import {NTag} from "naive-ui";

interface State {
    dictCache: Map<string, { list: SysDict[], default: SysDict }>
}


export const useDictStore = defineStore('dict-store', {
    persist: false,
    state: (): State => {
        return {
            dictCache: new Map<string, { list: SysDict[], default: SysDict }>()
        }
    },
    actions: {
        loadDict(dictCodes: string[]) {
            if (isNotEmpty(dictCodes)) {
                dictApi.mapByDictCodes(dictCodes).then(res => {
                    for (let dataCode in res.data) {
                        this.dictCache.set(dataCode, {
                            list: res.data[dataCode],
                            default: res.data[dataCode].find(dict => dict.defaultItem) ?? res.data[dataCode][0]
                        })
                    }
                })
            }
        },
        getDictList(dictCode: string): SysDict[] {
            if (this.dictCache.has(dictCode)) {
                return this.dictCache.get(dictCode)?.list ?? []
            }
            return []
        },
        getDictDefault(dictCode: string): SysDict {
            if (this.dictCache.has(dictCode)) {
                return this.dictCache.get(dictCode)?.default ?? {}
            }
            return {}
        },
        getDict(dictCode: string, dictValue: any): SysDict | any {
            const resolveDictValue = booleanToNumber(dictValue);
            const findDict = this.getDictList(dictCode).find(dict => dict.dictValue === resolveDictValue);
            if (!findDict) {
                console.warn(`未找到字典值：${dictCode} ${dictValue}`)
            }
            return findDict ?? resolveDictValue;
        },
        getDictName(dictCode: string, dictValue: any): string | any {
            return this.getDict(dictCode, dictValue)?.dictName ?? dictValue;
        },
        renderTag(dictCode: string, dictValue: any, size: 'small' | 'medium' | 'large' | 'tiny' = 'medium') {
            const dict = this.getDict(dictCode, dictValue);
            const renderType = dict ? dict.dictRenderType : 'default';
            const label = dict.dictName ? dict.dictName : dict;
            return h(NTag, {type: renderType, size: size}, {default: () => label})
        },
        getDictTextOptions(dictCode: string): ComputedRef<{
            label: string | undefined;
            value: string | number | undefined
        }[]> {
            return computed(() => {
                let dictList = this.getDictList(dictCode);
                // @ts-ignore
                return dictList.sort((a, b) => a.dictWeight - b.dictWeight).map((item) => {
                    return {
                        // @ts-ignore
                        label: item.dictName,
                        value: item.dictValue
                    }
                })
            })
        },
        getDictTagOptions(dictCode: string): {
            label: () => VNode;
            value: string | number | undefined
        }[] {
            return computed(() => {
                let dictList = this.getDictList(dictCode);
                // @ts-ignore
                return dictList.sort((a, b) => a.dictWeight - b.dictWeight).map((item) => {
                    return {
                        // @ts-ignore
                        label: () => h(NTag, {type: item.dictRenderType ?? 'default'}, {default: () => item.dictName}),
                        value: item.dictValue
                    }
                })
            }).value
        }
    }
})
